package cn.liontalk.consumer;

import cn.liontalk.entity.Order;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;


/**
 * @author ZhouZhe
 * @version 1.0
 * @description 消息的消费
 * @date 2018-12-09 13:48
 **/
@Component
public class OrderReceiver {


    /**
     * 如果知道消息体是 order 可以使用注解@Payload
     * 采用手动manual，参数中需要使用Channel
     * @param order 订单实体
     */
    /*@RabbitListener(bindings = @QueueBinding(
            value=@Queue(value = "order-queue",durable = "true"),
            exchange = @Exchange(name="order-exchange",durable = "true",type = "topic"),
            key = "order.*"
    ))
    @RabbitHandler
    public void onOrderMessage(@Payload Order order, @Headers Map<String,Object> headers, Channel channel) throws Exception{

        //消费者操作

        System.out.println("=======================收到消息=========================");
        System.out.println("订单id: " +order.getId());

        Long develeryTag  = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        //需要手工确认，给mq 一确认
        channel.basicAck(develeryTag,false);

    }*/

        //配置监听的哪一个队列，同时在没有queue和exchange的情况下会去创建并建立绑定关系
        @RabbitListener(bindings = @QueueBinding(
                value = @Queue(value = "order-queue",durable = "true"),
                exchange = @Exchange(name="order-exchange",durable = "true",type = "topic"),
                key = "order.*"
        )
        )
        @RabbitHandler//如果有消息过来，在消费的时候调用这个方法
        public void onOrderMessage(@Payload Order order, @Headers Map<String,Object> headers, Channel channel) throws IOException, IOException {
            //消费者操作
            System.out.println("---------收到消息，开始消费---------");
            System.out.println("订单ID："+order.getId());

            /**
             * Delivery Tag 用来标识信道中投递的消息。RabbitMQ 推送消息给 Consumer 时，会附带一个 Delivery Tag，
             * 以便 Consumer 可以在消息确认时告诉 RabbitMQ 到底是哪条消息被确认了。
             * RabbitMQ 保证在每个信道中，每条消息的 Delivery Tag 从 1 开始递增。
             */
            Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);

            /**
             *  multiple 取值为 false 时，表示通知 RabbitMQ 当前消息被确认
             *  如果为 true，则额外将比第一个参数指定的 delivery tag 小的消息一并确认
             */
            boolean multiple = false;

            //ACK,确认一条消息已经被消费
            channel.basicAck(deliveryTag,multiple);
        }


}
